NEC Interchannel Package Format
Archived from http://www.cinnamonpirate.com/docs/neicpak on 2006/2/7
Grudgingly copied and pasted from his browser by D

NEC Interchannel’s package format is used in the Sentimental Graffiti games to store scripts and other data. The format appears in both Sentimental Graffiti on Sega Saturn and Sentimental Graffiti 2 on Dreamcast (I think, it’s been a long time since I lost the GD-ROM dump I made of the later).

The format is similar to Fastfile in that it is done to cut down on how many open streams the game needs, but it differs in its structure. Instead of running the files together, it arranges the files so all begin at the next sector of the CD-ROM. Since sectors are 0×800 bytes in length, you can multiply the sector count given in the header by 0×800 to get the start offset for each file. The file is padded out to the next sector by 0×00 bytes.

All values are stored in big endian byte order, since the SH2 and SH4 are big endian processors:

File count [4 bytes, long]
(file loop)
  File offset [4 bytes, long]
  File size [4 bytes, long]
  File name [16 bytes, string]
(end loop)

A proof of concept extractor is shown below:

$fd = fopen('SCRIPT.PAK', 'rb');
list($junk, $count) = unpack('N*', fread($fd, 4));
$offset = array();
$filesize = array();
$name = array();
for($i=0; $i< $count; $i++) {
  list($junk, $offset[$i]) = 0x800 * unpack('N*', fread($fd, 4));
  list($junk, $filesize[$i]) = unpack('N*', fread($fd, 4));
  $filename[$i] = rtrim(fread($fd, 16));
}
for($i=0; $i<$count; $i++) {
  $fo = fopen($filename[$i], 'w');
  fseek($fd, $offset[$i], SEEK_SET);
  fputs($fo, fread($fd, $filesize[$i]));
  fclose($fo);
}
fclose($fd);